#!/usr/bin/php
<?php

const S_IFMT   = 0170000;
const S_IFSOCK = 0140000;
const S_IFLNK  = 0120000;
const S_IFREG  = 0100000;
const S_IFBLK  = 0060000;
const S_IFDIR  = 0040000;
const S_IFCHR  = 0020000;
const S_IFIFO  = 0010000;
const S_ISUID  = 04000;
const S_ISGID  = 02000;
const S_ISVTX  = 01000;
const S_IRWXU  = 00700;
const S_IRWXG  = 00070;
const S_IRWXO  = 00007;

const MONTH = [
    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
    [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
];

function ls_type($mode)
{
    switch ($mode & S_IFMT) {
        case S_IFSOCK:
            echo 's';
            break;
        case S_IFREG:
            echo '-';
            break;
        case S_IFDIR:
            echo 'd';
            break;
        case S_IFIFO:
            echo 'p';
            break;
        case S_IFBLK:
            echo 'b';
            break;
        case S_IFCHR:
            echo 'c';
            break;
        case S_IFLNK:
            echo 'l';
            break;
        default:
            break;
    }
}

function _perm($perm)
{
    switch ($perm) {
        case 1:
            echo '--x';
            break;
        case 2:
            echo '-w-';
            break;
        case 3:
            echo '-wx';
            break;
        case 4:
            echo 'r--';
            break;
        case 5:
            echo 'r-x';
            break;
        case 6:
            echo 'rw-';
            break;
        case 7:
            echo 'rwx';
            break;
        case 0:
        default:
            echo '---';
            break;
    }
}

function ls_perm($mode)
{
    _perm (($mode & S_IRWXU) >> 6);
    _perm (($mode & S_IRWXG) >> 3);
    _perm ($mode & S_IRWXO);
}

function _user($id, $file)
{
    $fp = fopen($file, "r");
    if ($fp === FALSE)
        goto ERR1;

    while (($s = fgets($fp)) !== FALSE) {
        $u = explode(":", $s);
        if ($u[3] == $id) {
            $id = $u[0];
            goto ERR2;
        }
    }

ERR2:
    fclose($fp);
ERR1:
    echo $id;
}

function ls_user($uid)
{
    _user($uid, "/etc/passwd");
}

function ls_group($gid)
{
    _user($gid, "/etc/group");
}

function isYear($year)
{
    if ($year % 400 == 0
            || $year % 4 == 0 && $year % 100 != 0)
        return true;
    return false;
}

function ls_date($time)
{
    // $days = (int)((time() / 60 / 60 + 8) / 24);
    $days = (int)(($time / 3600 + 8) / 24);
    $sec = $time - $days * 3600 * 24 + 8 * 3600;
    $year = 1970;
    $month = 1;
    $hour = 0;
    $min = 0;

    while ($days >= 365 + isYear($year)) {
        $days -= 365 + isYear($year++);
    }

    $y = isYear($year);

    while ($days >= MONTH[$y][$month - 1]) {
        $days -= MONTH[$y][$month++ - 1];
    }

    $day = $days + 1;

    $hour = (int)($sec / 3600);
    $sec -= $hour * 3600;
    $min = (int)($sec / 60);
    $sec -= $min * 60;

    $month = str_pad($month, 2, "0", STR_PAD_LEFT);
    $day = str_pad($day, 2, "0", STR_PAD_LEFT);
    $hour = str_pad($hour, 2, "0", STR_PAD_LEFT);
    $min = str_pad($min, 2, "0", STR_PAD_LEFT);
    $sec = str_pad($sec, 2, "0", STR_PAD_LEFT);

    echo "$year-$month-$day $hour:$min:$sec";
}

function main($argc, & $argv)
{
    if ($argc < 2)
        return 0;

    error_reporting(0);

    $st = lstat($argv[1]);
    if ($st === FALSE)
        return;

    // print_r($st);

    // echo "\t";

    ls_type($st['mode']);
    ls_perm($st['mode']);
    echo " ";
    ls_user($st['uid']);
    echo " ";
    ls_group($st['gid']);
    echo " ", $st['size'], " ";
    ls_date($st['mtime']);
    echo " ", $argv[1];

    if (is_link($argv[1]))
        echo ' -> ', readlink($argv[1]);

    echo PHP_EOL;

    return 0;
}

exit(main($argc, $argv));

